package com.mo.lib.utils

import android.app.Activity
import android.app.Application
import android.content.Context
import android.graphics.Point
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.os.Build
import android.view.*
import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.mo.lib.utils.res.ResUtil

/**
 * @ author：mo
 * @ data：2021/9/24:15:55
 * @ 功能：view相关
 */

@JvmOverloads fun Context.getView(layoutId: Int, group: ViewGroup? = null) = LayoutInflater.from(this).inflate(layoutId, group, false)

fun Context.getView(viewId: Int, @ColorInt backgroundColor: Int?, viewHeight: Int, viewWidth: Int): View? {
    if (this is Application) {
        KLog.i("Application不能作为载体创建view")
        return null
    } // 绘制一个和状态栏一样高的矩形
    val view = View(this)
    view.layoutParams = LinearLayout.LayoutParams(viewHeight, viewWidth)
    view.setBackgroundColor(backgroundColor ?: ResUtil.getColor("#FFFFFF"))
    view.id = viewId
    return view
}

fun Context.getView(viewId: Int, drawable: Drawable?, viewHeight: Int, viewWidth: Int): View? {
    if (this is Application) {
        KLog.i("Application不能作为载体创建view")
        return null
    } // 绘制一个和状态栏一样高的矩形
    val view = View(this)
    view.layoutParams = LinearLayout.LayoutParams(viewHeight, viewWidth)
    view.background = drawable
    view.id = viewId
    return view
}

/**
 * 设置布局参数
 * android:clipToPadding="true"
 * android:fitsSystemWindows="true"
 */
fun View.setViewfits(isTrue: Boolean?) {
    this.fitsSystemWindows = isTrue!!
    (this as ViewGroup).clipToPadding = isTrue
}

/** 扩大view触摸识别范围*/
fun View.setViewTouchExpand() {
    setViewTouchExpand(50)
}

/** 扩大view的触摸范围，最大不超过其父View范围方便触发点击事件*/
fun View.setViewTouchExpand(size: Int) {
    this.post {
        val rect = Rect()
        this.getHitRect(rect)
        rect.top -= size
        rect.bottom += size
        rect.left -= size
        rect.right += size
        (this.parent as View)?.setTouchDelegate(TouchDelegate(rect, this))
    }
}

/** 还原 View 的触摸和点击响应范围, 最小不小于 View 自身范围*/
fun View.setViewTouchRestore() {
    this.post {
        if (View::class.java.isInstance(this.parent)) {
            (this.parent as View).touchDelegate = TouchDelegate(Rect(), this)
        }
    }
}

/** 设置view的背景透明度,aph==0–255之间的数字。数字越大，越不透明。*/
fun View.setBackgroundAph(aph: Int) {
    if (aph in 0..255) { //mutate()的作用是通知系统，我的这个改变是独有的不共享，如果没有这个方法，在5.0以上的系统，view所用到的背景图片或者颜色值，在其他控件使用时会一起跟着变
        this.background.mutate().alpha = aph
    }
}

/** 给 View 设置背景, 用于简化 SDK 版本判断*/
fun View.setBackgroundD(drawable: Drawable) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        this.background = drawable
    } else {
        this.setBackgroundDrawable(drawable)
    }
}

fun View.setBackgroundColor(colorStr: String) = this.setBackgroundColor(ResUtil.getColor(colorStr))


/** 内容是否为空*/
fun View.isEmptyContext(): Boolean {
    return when (this) {
        is TextView -> this.text.length == 0
        is EditText -> this.text.length == 0
        is Button -> this.text.length == 0
        else -> true
    }
}

/**view是否被遮挡 */
fun isViewCovered(view: View): Boolean {
    var currentView = view
    val currentViewRect = Rect()
    val partVisible = currentView.getGlobalVisibleRect(currentViewRect)
    val totalHeightVisible = currentViewRect.bottom - currentViewRect.top >= view.measuredHeight
    val totalWidthVisible = currentViewRect.right - currentViewRect.left >= view.measuredWidth
    val totalViewVisible = partVisible && totalHeightVisible && totalWidthVisible // if any part of the view is clipped by any of its parents,return true
    if (!totalViewVisible) {
        return true
    }
    while (currentView.parent is ViewGroup) {
        val currentParent = currentView.parent as ViewGroup // if the parent of view is not visible,return true
        if (currentParent.visibility != View.VISIBLE) {
            return true
        }
        val start: Int = currentView.getViewOrderInParent(currentParent)
        for (i in start + 1 until currentParent.childCount) {
            val viewRect = Rect()
            view.getGlobalVisibleRect(viewRect)
            val otherView = currentParent.getChildAt(i)
            val otherViewRect = Rect()
            otherView.getGlobalVisibleRect(otherViewRect) // if view intersects its older brother(covered),return true
            if (Rect.intersects(viewRect, otherViewRect)) {
                return true
            }
        }
        currentView = currentParent
    }
    return false
}

/** 获取当前view位于父view中的顺序位置*/
fun View.getViewOrderInParent(parent: ViewGroup): Int {
    var index = 0
    while (index < parent.childCount) {
        if (parent.getChildAt(index) === this) {
            break
        }
        index++
    }
    return index
}

/**获取view在屏幕中的4个位置坐标，从屏幕左上角开始， [0] ==左x 坐标, [1] == 上y 坐标 ，[3] ==右x 坐标, [1] == 下y 坐标*/
fun View.getLocationsOnScreen4(): IntArray? {
    val location = getLocationOnScreen2()
    val locations = IntArray(4)
    locations[0] = location!![0]
    locations[1] = location[1]
    locations[2] = location[0] + this.width
    locations[3] = location[1] + this.height
    return locations
}

/**获取view在屏幕中的2个位置坐标，从屏幕左上角开始， [0] ==x 坐标, [1] == y 坐标 */
fun View.getLocationOnScreen2(): IntArray? {
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return location
}

/** 获取view尺寸 [0]==宽  [1]==高*/
fun View.getViewSize(): IntArray {
    val view = this
    val intArray = IntArray(2)
    val vto = view.viewTreeObserver
    vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            view.viewTreeObserver.removeGlobalOnLayoutListener(this)
            intArray[0] = view.width
            intArray[1] = view.height
        }
    })
    return intArray
}

/** 获取控件的高度*/
fun View.getViewMeasuredHeight(): Int {
    calculateViewMeasure(this)
    return this.measuredHeight
}

/** 获取控件的宽度*/
fun View.getViewMeasuredWidth(): Int {
    calculateViewMeasure(this)
    return this.measuredWidth
}

/** 测量控件的尺寸*/
private fun calculateViewMeasure(view: View) {
    val w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    val h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    view.measure(w, h)
}

/** view是否在屏幕里可见，true==屏幕里可见，false==不可见滑出去了，不在屏幕里*/
fun Activity.isViewCanSeeing(view: View): Boolean {
    val p = Point()
    this.windowManager.defaultDisplay.getSize(p)
    val screenWidth = p.x
    val screenHeight = p.y
    val rect = Rect(0, 0, screenWidth, screenHeight)
    val location = IntArray(2)
    view.getLocationInWindow(location)
    return view.getLocalVisibleRect(rect)
}

/** 判断当前用户触摸是否超出了View的显示区域*/
fun View.isOutOfBounds(event: MotionEvent): Boolean {
    val x = event.x.toInt()
    val y = event.y.toInt()
    val slop = ViewConfiguration.get(context).scaledWindowTouchSlop
    return (x < -slop || y < -slop || x > this.width + slop || y > this.height + slop)
}



